﻿#include <QThread>
#include <QDebug>
#include <QJsonObject>
#include <QFile>
#include <QDir>
#include <QJsonArray>
#include <QJsonDocument>
#include <QQmlContext>
#include <QDebug>
#include "DrillingrigQmlEvent.h"
#include "ControlBridge.h"
#include "ModbusClientProxy.h"
#include "Frameworks/DrillingrigMediator.h"
#include "Drillingrig.h"

Drillingrig::Drillingrig(QQmlContext* context, QObject* parent)
	: QObject(parent)
	, m_pluginsManager(new PluginsManager(context, this))
	, m_interaction(new DrillingrigQmlEvent(this))			//单次调度不可移动线程
	, m_mediator(new DrillingrigMediator(this))				//总调度 sync
{
	m_mediator->registerAction(static_cast<DrillingrigQmlEvent*>(m_interaction), DrillingrigEvent::Identity);
	connect(m_interaction, &DrillingrigQmlEvent::logReport, m_pluginsManager, &PluginsManager::logsHandle);
	m_mediator->registerAction(m_pluginsManager, PluginsManager::Identity);
	connect(m_pluginsManager, &PluginsManager::loadFinished, this, &Drillingrig::loadFinished);
	connect(m_pluginsManager, &PluginsManager::errors, this, &Drillingrig::errorText);
	QFile file(QDir::currentPath() + "/config/" + "PluginsConfig.json");
	if (!file.open(QIODevice::ReadOnly)) {
		std::throw_with_nested(std::logic_error("plugins Configs is not found!"));
	}
	QJsonArray arr = QJsonDocument::fromJson(file.readAll()).array();
	file.close();
	try {
		m_pluginsManager->load(std::move(arr));
	}
	catch (...) {
		auto eptr = std::current_exception();
		std::rethrow_exception(eptr);
	}
	m_asyncBridge = new QThread;
	m_bridge = new ControlBridge;							//监听 async
	m_bridge->moveToThread(m_asyncBridge);
	m_mediator->registerAction(m_bridge, ControlBridge::Identity);
	m_asyncBridge->start();
	connect(m_asyncBridge, &QThread::finished, m_bridge, &QObject::deleteLater);
	connect(m_bridge, &QObject::destroyed, m_asyncBridge, &QObject::deleteLater);

	m_asyncModbus = new QThread;
	m_modbus = new ModbusClientProxy;						//客户端轮询 async
	m_modbus->moveToThread(m_asyncModbus);
	m_mediator->registerAction(m_modbus, ModbusClientProxy::Identity);
	m_asyncModbus->start();
	connect(m_asyncModbus, &QThread::finished, m_modbus, &QObject::deleteLater);
	connect(m_modbus, &QObject::destroyed, m_asyncModbus, &QObject::deleteLater);

	context->setContextProperty("interaction", m_interaction);
}

Drillingrig::~Drillingrig() {
	qDebug() << __FUNCTION__;
	if (m_asyncBridge->isRunning()) {
		m_asyncBridge->quit();
		m_asyncBridge->wait();
	}
	if (m_asyncModbus->isRunning()) {
		m_asyncModbus->quit();
		m_asyncModbus->wait();
	}
}

void Drillingrig::setBridge(QJsonObject const& obj) {
	auto&& host = obj["host"].toString();
	auto&& port = obj["port"].toInt();
	auto&& device = obj["serverId"].toInt();
	if (!m_bridge->connectDevice(host, port, device)) {
		qWarning() << QStringLiteral("监听操作台通讯失败，检查网络环境后重启软件");
		m_mediator->reportLog(QStringLiteral("操作台->上位机:监听modbus服务失败"), 2);
	}
}

void Drillingrig::setIOAction(EquipmentAction* action) {
	m_mediator->registerAction(action, action->identity());
}

void Drillingrig::setModbus(QJsonObject const& obj) {
	if (!m_modbus->connectDevice(obj)) {
		qWarning() << QStringLiteral("监听modbus服务失败，检查网络环境后重启软件");
		m_mediator->reportLog(QStringLiteral("上位机->下位机:监听modbus服务失败"), 2);
	}
}
